import { Row, Col, Card, Spin, Tree } from 'antd';
import React, { useState } from 'react';
import TreeControlled from '@/components/blocks/TreeControlled';
import { useRequest } from '@umijs/hooks';
import { findRoleByUpdate } from '../../service';
import { SettingOutlined } from '@ant-design/icons';

const { TreeNode } = Tree;

export default function Step2(props) {
  const { checkedRoleKeys, setCheckedRoleKeys, setPreCheckedRoleKeys, data } = props;
  const [subRoleTree, setSubRoleTree] = useState([]);
  const [localRoles, setLocalRoles] = useState([]);
  const [preDisabledKeys, setPreDisabledKeys] = useState([]);
  const disableAdminRoles = function disableAdminRoles(roles, checkedKeys, disabledRoles) {
    const adminChecked = roles.some(
      item => item.competence === '0' && checkedKeys.some(key => key === item.key),
    );
    if (adminChecked) {
      return roles.map(item => ({
        ...item,
        disabled: item.competence === '0' && checkedKeys.every(key => key !== item.key),
      }));
    } else {
      return roles.map(item => ({
        ...item,
        disabled: disabledRoles.some(preKey => preKey === item.key),
      }));
    }
  };

  const reBuildTree = function reBuildTree(tree, keys) {
    if (keys && tree.length > 0) {
      const subTree = tree
        .filter(item => ~keys.indexOf(item.key))
        .map(item => item.children)
        .reduce(distinctMergeTree, []);
      setSubRoleTree(subTree);
    } else {
      setSubRoleTree([]);
    }
  };

  const { data: roleTree = [], loading: roleTreeLoading } = useRequest(
    () => findRoleByUpdate({ userId: data.id }),
    {
      refreshDeps: [data.id],
      onSuccess(res = []) {
        if (res.length > 0) {
          const checkedRoles = res.filter(item => item.isChecked === '1').map(item => item.key);
          const disabledRoles = res.filter(item => item.disabled).map(item => item.key);
          setPreCheckedRoleKeys(checkedRoles);
          setPreDisabledKeys(disabledRoles);
          setCheckedRoleKeys(checkedRoles);
          const flatRoles = res.map(item => ({ ...item, children: [] }));
          reBuildTree(res, checkedRoles);
          setLocalRoles(disableAdminRoles(flatRoles, checkedRoles, disabledRoles));
        }
      },
    },
  );

  const distinctMergeTree = function distinctMergeTree(source, target) {
    if (!target || target.length <= 0) {
      return source || [];
    }
    if (!source || source.length <= 0) {
      return target || [];
    }

    return source
      .reduce((pre, cur) => {
        const sameItem = target.find(item => item.key === cur.key);
        if (sameItem) {
          return pre.concat([
            { ...cur, children: distinctMergeTree(cur.children, sameItem.children) },
          ]);
        } else {
          return pre.concat([cur]);
        }
      }, [])
      .concat(target.filter(item => !source.some(innerItem => item.key === innerItem.key)));
  };

  const onSetCheckedKeys = keys => {
    setCheckedRoleKeys(keys);
    reBuildTree(roleTree, keys);
    setLocalRoles(disableAdminRoles(localRoles, keys, preDisabledKeys));
  };

  const renderTitle = (disabled, competence, title) => {
    return competence === '0' ? (
      <span title={disabled ? '当前管理员角色下已有用户， 不可重复设置' : title}>
        <SettingOutlined /> {title}
      </span>
    ) : (
      <span title={title} style={{ marginLeft: 16 }}>
        {title}
      </span>
    );
  };

  const renderTreeNodes = data =>
    data.map(({ title, ...item }) => {
      if (item.children) {
        return (
          <TreeNode
            title={renderTitle(item.disabled, item.competence, title)}
            key={item.key}
            {...item}
            dataRef={item}
          >
            {renderTreeNodes(item.children)}
          </TreeNode>
        );
      }
      return (
        <TreeNode
          title={renderTitle(item.disabled, item.competence, title)}
          key={item.key}
          {...item}
        />
      );
    });

  return (
    <Row type="flex" gutter={8}>
      <Col span={10} style={{ minHeight: 100 }}>
        <Card
          title="角色选择"
          bodyStyle={{
            padding: '8px',
            overflow: 'auto',
            height: 300,
          }}
        >
          <Spin spinning={roleTreeLoading}>
            <TreeControlled
              checkable
              renderTreeNodes={renderTreeNodes}
              data={localRoles}
              checkedKeys={checkedRoleKeys}
              setCheckedKeys={onSetCheckedKeys}
            />
          </Spin>
        </Card>
      </Col>
      <Col span={14}>
        <Card
          title="权限预览"
          bodyStyle={{
            padding: '8px',
            overflow: 'auto',
            height: 300,
          }}
        >
          <TreeControlled data={subRoleTree} />
        </Card>
      </Col>
    </Row>
  );
}
